package com.PictureSite.DatabaseAccess;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import com.PictureSite.model.UserPost;
import com.PictureSite.model.Voter;
import com.google.appengine.api.datastore.DatastoreFailureException;
import com.google.appengine.api.datastore.DatastoreService;
import com.google.appengine.api.datastore.DatastoreServiceFactory;
import com.google.appengine.api.datastore.Entity;
import com.google.appengine.api.datastore.EntityNotFoundException;
import com.google.appengine.api.datastore.FetchOptions;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.api.datastore.PreparedQuery;
import com.google.appengine.api.datastore.Query;
import com.google.appengine.api.datastore.Query.FilterOperator;

public class PictureSiteCreatePostDAO implements GenericDAO {
	
	private DatastoreService datastore = DatastoreServiceFactory.getDatastoreService();

	@Override
	public void storePost(UserPost newPost) {
		Entity picturePost = new Entity("PicturePost");
		try {
			picturePost.setProperty("userName", newPost.getUserName());
			picturePost.setProperty("title", newPost.getTitle());
			picturePost.setProperty("date", newPost.getDatePosted());
			picturePost.setProperty("blobId", newPost.getBlobId());
			picturePost.setProperty("likes", newPost.getVotes());
			picturePost.setProperty("userIp", newPost.getUserIp());
			
			datastore.put(picturePost);
		} catch (DatastoreFailureException e) {
			
		}
	}

	@Override
	public List<Entity> getPostByDateDesc(int pageLimit, int pageNumber) {
		Query query = new Query("PicturePost").addSort("date",Query.SortDirection.DESCENDING);
		List<Entity> results;
		
		results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(pageLimit)
										.offset(pageLimit*(pageNumber-1)));
		
		return results;
	}
	
	@Override
	public boolean isLastImagePage(int pageLimit, int pageNumber) {
		Query query = new Query("PicturePost").addSort("date",Query.SortDirection.DESCENDING);
		List<Entity> results;
		
		results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(pageLimit)
										.offset(pageLimit*(pageNumber)));
		
		boolean lastPage = results.isEmpty();
	
		return lastPage;
	}
	
	@Override
	public Map<String, Object> getPostFromId(UserPost userPost) throws EntityNotFoundException {
		Map<String, Object> parameters = new HashMap<String, Object>();
		
		parameters = datastore.get(KeyFactory.createKey("PicturePost",Long.valueOf(userPost.getId()))).getProperties();
		return parameters;
	}
	
	@Override
	public void storeVotes(UserPost userPost, Voter voter) throws Exception {	
		Entity picturePost;
		picturePost = datastore.get(KeyFactory.createKey("PicturePost",Long.valueOf(userPost.getId())));
		picturePost.setProperty("likes", userPost.getVotes());
		datastore.put(picturePost);
		
		Entity newVoter = new Entity("Voters");
		newVoter.setProperty("userPostId", voter.getPostId());
		newVoter.setProperty("voterIp", voter.getIp());
		newVoter.setProperty("upVote", voter.getUpVote());
		datastore.put(newVoter);
	}

	@Override
	public List<String> getIpsForUserPost(String id) throws Exception {
		
		List<String> ips = new ArrayList<String>();

		Query q = new Query("Voters");
	    q.setFilter(FilterOperator.EQUAL.of("userPostId",id));
	    PreparedQuery pq =  datastore.prepare(q);
		
		for (Entity result : pq.asIterable())
		{
			ips.add(result.getProperty("voterIp").toString());
		}
		return ips;
	}
	
	@Override
	public Boolean getVoters(String id, String ip) throws Exception {
		Boolean upVote = null;
		Query q = new Query("Voters");
	    q.setFilter(FilterOperator.EQUAL.of("userPostId",id));
	    PreparedQuery pq =  datastore.prepare(q);
		
		for (Entity result : pq.asIterable())
		{
			if(ip.equals(result.getProperty("voterIp").toString())) {
				upVote = (Boolean) result.getProperty("upVote");
			}
		}
		return upVote;
	}

	@Override
	public void changeVote(UserPost userPost,Voter voter, String type) throws Exception {
		Entity picturePost;
		picturePost = datastore.get(KeyFactory.createKey("PicturePost",Long.valueOf(userPost.getId())));
		picturePost.setProperty("likes", userPost.getVotes());
		datastore.put(picturePost);
		
		Entity voterEntity = null;
		Query q = new Query("Voters");
	    q.setFilter(FilterOperator.EQUAL.of("userPostId",voter.getPostId()));
	    PreparedQuery pq =  datastore.prepare(q);
		
		for (Entity result : pq.asIterable())
		{
			if(voter.getIp().toString().equals(result.getProperty("voterIp").toString())) {
				voterEntity = datastore.get(result.getKey());
			}
		}
		voterEntity.setProperty("upVote", voter.getUpVote());
		datastore.put(voterEntity);
	}

	@Override
	public Boolean getVoteType(String id) {
		
		String voteType = null;

		Query q = new Query("Voters");
	    q.setFilter(FilterOperator.EQUAL.of("userPostId",id));
	    PreparedQuery pq =  datastore.prepare(q);
		
		for (Entity result : pq.asIterable())
		{
			voteType = result.getProperty("upVote").toString();
		}
		if (voteType == null) {
			return null;
		}
		return Boolean.valueOf(voteType);
	}
	
	@Override
	public List<Entity> getTopFiveRatedPost() {
		Query query = new Query("PicturePost").addSort("likes",Query.SortDirection.DESCENDING);
		List<Entity> results;
		
		results = datastore.prepare(query).asList(FetchOptions.Builder.withLimit(5));
		
		return results;
		
	}
}
